local json_util = require("com.ea.util.json")
local util = require "com.ea.util.utils";
local beanFactory = luastar_context.getBeanFactory();
local setmetatable = setmetatable;
----local logger=logger;
--
--
local _M={};
_M._VERSION="1.0";
local _mt={__index=_M};
setmetatable(_M,_mt);

--[[检查URL地址是否允许访问列表中，即config的permitURL中]]

function _M.beforeHandle()
   local appConfig=luastar_context.loadJsonConfig("config");
   if _.isEmpty(appConfig.req_limits) then
      return true;
   end
   --local req_limits,err = cjson.decode(appConfig.req_limits);  
   local req_limits=appConfig.req_limits; 
   local req_limit_uri,req_limit_limits,req_limit_key=nil,nil,nil;
   for itemIndex,itemValue in pairs(req_limits) do
       if ngx.var.APP_DEBUG_LOG== "true" then ngx.log(ngx.DEBUG,logger.formatMsg(string.format("req.uri=%s  req_limit_uri=%s",ngx.var.uri,itemValue["uri"]))) end
       if itemValue["uri"]==ngx.var.uri then
          req_limit_uri=itemValue["uri"];
          req_limit_limits=itemValue["limits"];
          req_limit_key=itemValue["key"];
          break;
       end
   end
   if req_limit_uri==nil then
       return true;
   end
   
    if ngx.var.APP_DEBUG_LOG== "true" then ngx.log(ngx.DEBUG,logger.formatMsg(string.format("req.uri need check_req_limits uri=%s",req_limit_uri))); end
    local keyParams=util:split(req_limit_key,";");
    local key ="";
    local last_req_args = util:get_req_args_all();
    for i,v in pairs(keyParams) do
       if ngx.var.APP_DEBUG_LOG== "true" then ngx.log(ngx.DEBUG,logger.formatMsg(string.format("key = %s  index=%s",v,i))) end
       local paramValue = util:get_req_param(v,last_req_args);
       if paramValue ==nil then
           paramValue=""
       end
       key=key.."_"..v.."_"..paramValue;
    end
    local newKey="req_limit:"..req_limit_uri..":"..key;
    
    local redis_bean = beanFactory:getBean("bean_redis_accesslayer"); 


    local limitTime=req_limit_limits+0;
    if ngx.var.APP_DEBUG_LOG== "true" then ngx.log(ngx.DEBUG,logger.formatMsg(string.format("newkey =%s",newKey))) end
    local rc = redis_bean:getConnect();
    if not rc then --连接不上redis不能影响主逻辑执行。
       if ngx.var.APP_DEBUG_LOG== "true" then ngx.log(ngx.DEBUG,logger.formatMsg(string.format("Redis链接失败"))); end
       return  true;
    end
    
    local ret,err=rc:multi();
    if ngx.var.APP_DEBUG_LOG== "true" then ngx.log(ngx.DEBUG,logger.formatMsg(string.format("multi result is %s ,error is %s",ret,err))) end
    local newKeyvalue,err=rc:incr(newKey);
    if ngx.var.APP_DEBUG_LOG== "true" then ngx.log(ngx.DEBUG,logger.formatMsg(string.format("incr result is %s ,error is %s",ret,err))) end
    local ret,err = rc:expire(newKey,limitTime);
    if ngx.var.APP_DEBUG_LOG== "true" then ngx.log(ngx.DEBUG,logger.formatMsg(string.format("expire result is %s ,error is %s",ret,err))) end
    local ret,err = rc:exec();
    redis_bean:close(rc);
    if ngx.var.APP_DEBUG_LOG== "true" then ngx.log(ngx.DEBUG,logger.formatMsg(string.format("exec result is %s ,error is %s",ret,err))) end
    if err==nil then
       if ret[1]>1 then               
          if ngx.var.APP_DEBUG_LOG== "true" then ngx.log(ngx.DEBUG,logger.formatMsg(string.format("key %s  is forbiden outof req-limits %s,key req times is %s",newKey,limitTime,ret[1]))) ; end
          ngx.log(ngx.INFO,logger.formatMsg(string.format("用户操作频繁，禁止访问。 URI：",ngx.var.uri)));
          return false, cjson.encode({state=4020002,msg="亲，操作太快了，哀家不知道怎么办了。您稍后再试试吧。",data=nil});
       end
    end     
 
  return true

end

function _M.afterHandle(ctrl_call_ok, err_info)
    if not ctrl_call_ok then
        ngx.ctx.response:writeln(json_util.exp(err_info))
    end
end


return _M;
